﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using Transfer.Utils;

namespace QuickModel.ColumnTransModel
{
	public class StrangeColumnFamilySymbolCreator
	{
		public StrangeColumnFamilySymbolCreator(Autodesk.Revit.DB.Document doc, XYZ ptPos, List<Curve> lstLoopCurve, string strTemplateFilePath)
		{
			this.m_doc = doc;
			this.m_ptPos = ptPos;
			this.m_lstLoopCurve = lstLoopCurve;
			this.m_strTemplateFilePath = strTemplateFilePath;
		}

		public FamilySymbol CreateStrangeColumnFamilySymbol(string strFamilyName, string strFamilySymbolName)
		{
			Document document = this.m_doc.Application.NewFamilyDocument(this.m_strTemplateFilePath);
			Transaction transaction = new Transaction(document, "Create Family");
			try
			{
				transaction.Start();
				Extrusion parameter = this.CreateExtrusion(document);
				this.SetParameter(parameter);
				transaction.Commit();
			}
			catch (Exception)
			{
				bool flag = transaction.HasStarted();
				if (flag)
				{
					transaction.RollBack();
				}
				return null;
			}
			Family family = document.LoadFamily(this.m_doc);
			document.Close(false);
			Transaction transaction2 = new Transaction(this.m_doc, "Rename");
			FamilySymbol familySymbol = null;
			try
			{
				transaction2.Start();
				family.Name = strFamilyName;
				List<FamilySymbol> symbols = family.GetSymbols();
				FamilySymbol familySymbol2 = symbols.FirstOrDefault<FamilySymbol>();
				familySymbol = symbols.Find((FamilySymbol item) => item.Name == strFamilySymbolName);
				bool flag2 = familySymbol == null;
				if (flag2)
				{
					familySymbol = (familySymbol2.Duplicate(strFamilySymbolName) as FamilySymbol);
				}
				transaction2.Commit();
			}
			catch (Exception)
			{
				bool flag3 = transaction2.HasStarted();
				if (flag3)
				{
					transaction2.RollBack();
				}
				return null;
			}
			return familySymbol;
		}

		private Extrusion CreateExtrusion(Autodesk.Revit.DB.Document docFamilyTmplate)
		{
			Extrusion result = null;
			try
			{
				CurveArrArray curveArrArray = new CurveArrArray();
				CurveArray curveArray = new CurveArray();
				Transform transform = Transform.CreateTranslation(XYZ.Zero - this.m_ptPos);
				foreach (Curve curve in this.m_lstLoopCurve)
				{
					curveArray.Append(curve.CreateTransformed(transform));
				}
				curveArrArray.Append(curveArray);
				Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, this.m_ptPos);
				SketchPlane sketchPlane = SketchPlane.Create(docFamilyTmplate, plane);
				result = docFamilyTmplate.FamilyCreate.NewExtrusion(true, curveArrArray, sketchPlane, Common.MMToFeet(4000.0));
			}
			catch (Exception)
			{
			}
			return result;
		}

		private PlanarFace GetExtrusionPlaneFace(Extrusion extrusion, Autodesk.Revit.DB.View view, XYZ normal)
		{
			FaceArray faceArray = null;
			bool isSolid = extrusion.IsSolid;
			if (isSolid)
			{
				foreach (GeometryObject geometryObject in extrusion.get_Geometry(new Options
				{
					ComputeReferences = true,
					View = view
				}))
				{
					bool flag = geometryObject is Solid;
					if (flag)
					{
						Solid solid = geometryObject as Solid;
						faceArray = solid.Faces;
						bool flag2 = faceArray.Size > 0;
						if (flag2)
						{
							break;
						}
					}
				}
				foreach (object obj in faceArray)
				{
					Face face = (Face)obj;
					PlanarFace planarFace = face as PlanarFace;
					bool flag3 = planarFace != null && planarFace.FaceNormal.IsAlmostEqualTo(normal);
					if (flag3)
					{
						return planarFace;
					}
				}
			}
			return null;
		}

		private void SetParameter(Extrusion extrusion)
		{
			Document document = extrusion.Document;
			Autodesk.Revit.DB.View view = null;
			Level level = null;
			Level level2 = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			filteredElementCollector.OfClass(typeof(Autodesk.Revit.DB.View));
			foreach (Element element in filteredElementCollector)
			{
				Autodesk.Revit.DB.View view2 = (Autodesk.Revit.DB.View)element;
				bool flag = view2.Name.CompareTo("前") == 0 || view2.Name.CompareTo("Front") == 0;
				if (flag)
				{
					view = view2;
				}
				else
				{
					bool flag2 = view2.Name.CompareTo("右") == 0 || view2.Name.CompareTo("Right") == 0;
					if (!flag2)
					{
						bool flag3 = (view2.Name.CompareTo("低于参照标高") == 0 || view2.Name.CompareTo("Lower Ref. Level") == 0) && (int)view2.ViewType == 1;
						if (flag3)
						{
						}
					}
				}
			}
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(document);
			filteredElementCollector2.OfClass(typeof(Level));
			foreach (Element element2 in filteredElementCollector2)
			{
				Level level3 = (Level)element2;
				bool flag4 = level3.Name.CompareTo("低于参照标高") == 0 || level3.Name.CompareTo("Lower Ref. Level") == 0;
				if (flag4)
				{
					level = level3;
				}
				else
				{
					bool flag5 = level3.Name.CompareTo("高于参照标高") == 0 || level3.Name.CompareTo("Upper Ref Level") == 0;
					if (flag5)
					{
						level2 = level3;
					}
				}
			}
			Face extrusionPlaneFace = this.GetExtrusionPlaneFace(extrusion, view, XYZ.BasisZ);
			bool flag6 = extrusionPlaneFace != null;
			if (flag6)
			{
				Reference planeReference = level2.GetPlaneReference();
				document.FamilyCreate.NewAlignment(view, planeReference, extrusionPlaneFace.Reference);
			}
			Face extrusionPlaneFace2 = this.GetExtrusionPlaneFace(extrusion, view, -XYZ.BasisZ);
			bool flag7 = extrusionPlaneFace2 != null;
			if (flag7)
			{
				Reference planeReference2 = level.GetPlaneReference();
				document.FamilyCreate.NewAlignment(view, planeReference2, extrusionPlaneFace2.Reference);
			}
		}

		private string m_strTemplateFilePath = string.Empty;

		private List<Curve> m_lstLoopCurve = new List<Curve>();

		private XYZ m_ptPos = new XYZ();

		private Document m_doc = null;
	}
}
